# -*- coding: utf-8 -*-

"""
  Support thread.

  author sato.tatsuma
"""

import sys
from threading import Thread, Event
from ddns_valuedomain import DdnsValueDomain
from exception import InvalidRequest, InvalidDomainPassword, InvalidHost, InvalidIPAddress
from exception import PasswordError, ServerBusy, UnknownError

class DdnsThread(Thread):
  """
    Thread class.
  """
  def __init__(self, setting):
    Thread.__init__(self)
    self.stopevent = Event()
    self.setting = setting
    self.ipaddress = None

  def run(self):
    """
      run() will called by Thread.start().
    """
    ddns = DdnsValueDomain(
        self.setting['domain'],
        self.setting['password'],
        self.setting['request_domain'],
        self.setting['request_url'],
        self.setting['domain_host'],
        self.setting['ipaddress'])
    self.ddns = ddns

    wait_seconds = 0
    # Do once in start up process.
    self.process_ddns()

    while not self.stopevent.isSet():
      if wait_seconds > self.setting['interval']:
        self.process_ddns()
        wait_seconds = 0

        # Flush logs.
        for f in sys.stdout, sys.stderr:
          f.flush()

      # thread will sleep 3 seconds.
      # Don't set large seconds to known join was called.
      self.stopevent.wait(3)
      wait_seconds += 3

  def join(self, timeout=None):
    """
      Stop the thread and wait for it to end.
    """
    self.stopevent.set()
    Thread.join(self, timeout)

  def process_ddns(self):
    """
      Main process.
    """
    if self.setting['update_ipaddress']:
      self.ddns.update_ipaddress()

    if self.ipaddress != self.ddns.ipaddress or self.setting['force_update']:
      # IP address has changed or set force_update option.
      try:
        self.ddns.update_dns()
      except InvalidRequest, e:
        # Can't retry.
        # End this thread.
        sys.stderr(e.message)
        self.join()
      except InvalidDomainPassword, e:
        # Can't retry.
        # End this thread.
        sys.stderr(e.message)
        self.join()
      except InvalidHost, e:
        # Can't retry.
        # End this thread.
        sys.stderr(e.message)
        self.join()
      except InvalidIPAddress, e:
        # Can't retry.
        # End this thread.
        sys.stderr(e.message)
        self.join()
      except UnknownError, e:
        # Can't retry.
        # End this thread.
        sys.stderr(e.message)
        self.join()
      except ServerBusy:
        # Can retry.
        None
      else:
        # Update IP address buffer.
        self.ipaddress = self.ddns.ipaddress
